package websocket

import (
	"encoding/json"
	"time"

	"github.com/zeromicro/go-zero/core/logx"
)

// MessageProcessor 统一的消息处理器
type MessageProcessor struct {
	server *WebSocketServer
}

// NewMessageProcessor 创建新的消息处理器
func NewMessageProcessor(server *WebSocketServer) *MessageProcessor {
	return &MessageProcessor{
		server: server,
	}
}

// ProcessMessage 处理消息
func (mp *MessageProcessor) ProcessMessage(client *Client, message Message, room *Room) error {
	switch message.Type {
	case int(MessageTypeText):
		return mp.handleTextMessage(client, message, room)
	case int(MessageTypeReady):
		return mp.handleReadyMessage(client, message, room)
	case int(MessageTypeGameOp):
		return mp.handleGameOpMessage(client, message, room)
	case int(MessageTypeRead):
		return mp.handleReadMessage(client, message, room)
	case int(MessageTypeTravelNotice):
		return mp.handleTravelNoticeMessage(client, message, room)
	default:
		// 其他消息类型直接广播
		room.Broadcast(message)
		return nil
	}
}

// handleTextMessage 处理文本消息
func (mp *MessageProcessor) handleTextMessage(client *Client, message Message, room *Room) error {
	// 直接广播文本消息
	room.Broadcast(message)
	return nil
}

// handleReadyMessage 处理准备状态消息
func (mp *MessageProcessor) handleReadyMessage(client *Client, message Message, room *Room) error {
	// 更新准备状态
	room.mu.Lock()
	room.Ready[client.UserID] = message.Content == "true"
	room.mu.Unlock()

	// 广播准备状态变更
	readyMsg := Message{
		Type:     int(MessageTypeReady),
		UserID:   client.UserID,
		UserName: client.UserName,
		Content:  message.Content,
		Time:     time.Now().Unix(),
	}
	room.Broadcast(readyMsg)

	// 广播房间列表更新
	if mp.server != nil {
		go mp.server.BroadcastRoomListUpdate()
	}

	// 检查是否所有用户都已准备
	allReady := true
	room.mu.RLock()
	for _, ready := range room.Ready {
		if !ready {
			allReady = false
			break
		}
	}
	userCount := len(room.Clients)
	room.mu.RUnlock()

	// 如果所有用户都已准备且人数大于1，可以开始游戏
	if allReady && userCount > 1 && room.Type != "chat" {
		mp.startGame(room)
	}

	return nil
}

// handleGameOpMessage 处理游戏操作消息
func (mp *MessageProcessor) handleGameOpMessage(client *Client, message Message, room *Room) error {
	// 解析游戏操作
	var gameOp GameOp
	if err := json.Unmarshal([]byte(message.Content), &gameOp); err != nil {
		logx.Errorf("[MessageProcessor] 解析游戏操作失败: %v", err)
		return err
	}

	// 处理游戏操作
	mp.handleGameOp(room, client.UserID, gameOp)
	return nil
}

// handleReadMessage 处理已读消息
func (mp *MessageProcessor) handleReadMessage(client *Client, message Message, room *Room) error {
	messageID := message.Content
	mp.setMessageRead(room, client.UserID, messageID)
	return nil
}

// handleGameOp 处理游戏操作
func (mp *MessageProcessor) handleGameOp(room *Room, userID string, op GameOp) {
	// 这里应该根据游戏类型处理不同的操作
	// 暂时只是记录日志
	logx.Infof("[MessageProcessor] 用户 %s 执行游戏操作: %s", userID, op.Op)
}

// handleTravelNoticeMessage 处理虚拟旅行通知消息
func (mp *MessageProcessor) handleTravelNoticeMessage(client *Client, message Message, room *Room) error {
	// 虚拟旅行通知消息直接广播给房间内所有用户
	room.Broadcast(message)
	return nil
}

// setMessageRead 设置消息已读
func (mp *MessageProcessor) setMessageRead(room *Room, userID, messageID string) {
	// 这里应该实现消息已读逻辑
	logx.Infof("[MessageProcessor] 用户 %s 标记消息 %s 为已读", userID, messageID)
}

// startGame 开始游戏
func (mp *MessageProcessor) startGame(room *Room) {
	if room.Type == "chat" {
		return
	}

	// 初始化游戏状态
	room.gameMu.Lock()
	if room.GameState == nil {
		room.GameState = &GameState{
			Status:  "waiting",
			Snakes:  make(map[string]*Snake),
			Foods:   []SnakeSegment{},
			Scores:  make(map[string]int),
			Ready:   make(map[string]bool),
			Players: make(map[string]*PlayerInfo),
		}
	}
	room.GameState.Status = "playing"
	room.GameState.StartTime = time.Now().Unix()
	room.gameMu.Unlock()

	// 广播游戏开始消息
	startMsg := Message{
		Type:    int(MessageTypeGameStart),
		Content: "游戏开始",
		Time:    time.Now().Unix(),
	}
	room.Broadcast(startMsg)

	logx.Infof("[MessageProcessor] 房间 %s 游戏开始", room.ID)
}

// CreateStandardMessageProcessor 创建标准消息处理器
func CreateStandardMessageProcessor() *MessageProcessor {
	return &MessageProcessor{}
}
